﻿/*
===========================================================================

  Copyright (c) 2010-2014 Darkstar Dev Teams

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see http://www.gnu.org/licenses/

  This file is part of DarkStar-server source code.

===========================================================================
*/

#ifndef _CHARUTILS_H
#define _CHARUTILS_H

#include "../../common/cbasetypes.h"

#include "../trait.h"
#include "../entities/charentity.h"

class CPetEntity;
class CMobEntity;
class CMeritPoints;

namespace charutils
{

	void	LoadExpTable();
	void	LoadChar(CCharEntity* PChar);
	void	LoadInventory(CCharEntity* PChar);

	void	SendQuestMissionLog(CCharEntity* PChar);
	void	SendKeyItems(CCharEntity* PChar);
	void	SendInventory(CCharEntity* PChar);

	void	CalculateStats(CCharEntity* PChar);
    void    UpdateSubJob(CCharEntity* PChar);

	void	SetLevelRestriction(CCharEntity* PChar, uint8 lvl);

	uint32	GetExpNEXTLevel(uint8 charlvl);
	uint32	GetRealExp(uint8 charlvl, uint8 moblvl);

	void	DelExperiencePoints(CCharEntity* PChar, float retainpct);
	void	DistributeExperiencePoints(CCharEntity* PChar, CMobEntity* PMob);
	void	DistributeGil(CCharEntity* PChar, CMobEntity* PMob);
    void	AddExperiencePoints(bool expFromRaise, CCharEntity* PChar, CBaseEntity* PMob, uint32 exp, uint32 baseexp = 0, bool isexpchain = false);
    void    RemoveExp(CCharEntity* PChar, int16 exploss);

	void	TrySkillUP(CCharEntity* PChar, SKILLTYPE SkillID, uint8 lvl);
	void	BuildingCharSkillsTable(CCharEntity* PChar);
	void    BuildingCharWeaponSkills(CCharEntity* PChar);
	void	BuildingCharAbilityTable(CCharEntity* PChar);
	void	BuildingCharTraitsTable(CCharEntity* PChar);
	void    BuildingCharPetAbilityTable(CCharEntity* PChar, CPetEntity* PPet, uint32 PetID);

    void    DoTrade(CCharEntity* PChar, CCharEntity* PTarget);
    bool    CanTrade(CCharEntity* PChar, CCharEntity* PTarget);

	void	CheckWeaponSkill(CCharEntity* PChar, uint8 skill);
    bool    HasItem(CCharEntity* PChar, uint16 ItemID);
    uint8   AddItem(CCharEntity* PChar, uint8 LocationID, CItem* PItem, bool silence = false);
	uint8	AddItem(CCharEntity* PChar, uint8 LocationID, uint16 itemID, uint32 quantity = 1, bool silence = false);
    uint8   MoveItem(CCharEntity* PChar, uint8 LocationID, uint8 SlotID, uint8 NewSlotID);
	uint32	UpdateItem(CCharEntity* PChar, uint8 LocationID, uint8 slotID, int32 quantity);
	void	CheckValidEquipment(CCharEntity* PChar);
	void	CheckEquipLogic(CCharEntity* PChar, SCRIPTTYPE ScriptType, uint32 param);
	void	EquipItem(CCharEntity* PChar, uint8 slotID, uint8 equipSlotID, uint8 containerID);
	void	UnequipItem(CCharEntity* PChar, uint8 equipSlotID);
    void    RemoveSub(CCharEntity* PChar);
    bool    EquipArmor(CCharEntity* PChar, uint8 slotID, uint8 equipSlotID);
	void	CheckUnarmedWeapon(CCharEntity* PChar);

    void    UpdateHealth(CCharEntity* PChar);

	int32	hasKeyItem(CCharEntity* PChar, uint16 KeyItemID);	        // Check for a key item
	int32	seenKeyItem(CCharEntity* PChar, uint16 KeyItemID);	        // Check to see if there was a description of the key subject read
	int32	unseenKeyItem(CCharEntity* PChar, uint16 KeyItemID);        // Attempt to remove keyitem from seen list
	int32	addKeyItem(CCharEntity* PChar, uint16 KeyItemID);	        // Add key item
	int32	delKeyItem(CCharEntity* PChar, uint16 KeyItemID);	        // Delete key item

	int32	hasSpell(CCharEntity* PChar, uint16 SpellID);		        // Check for spell
	int32	addSpell(CCharEntity* PChar, uint16 SpellID);		        // Add spell
	int32	delSpell(CCharEntity* PChar, uint16 SpellID);		        // Delete spell

	int32	hasLearnedAbility(CCharEntity* PChar, uint16 AbilityID);	// Check for an ability
	int32	addLearnedAbility(CCharEntity* PChar, uint16 AbilityID);	// Add ability
	int32	delLearnedAbility(CCharEntity* PChar, uint16 AbilityID);	// Delete ability

	int32	hasAbility(CCharEntity* PChar, uint16 AbilityID);	        // Check for an ability
	int32	addAbility(CCharEntity* PChar, uint16 AbilityID);	        // Add ability
	int32	delAbility(CCharEntity* PChar, uint16 AbilityID);	        // Delete ability

    int32   hasTitle(CCharEntity* PChar, uint16 Title);
    int32   addTitle(CCharEntity* PChar, uint16 Title);
    int32   delTitle(CCharEntity* PChar, uint16 Title);
    void    setTitle(CCharEntity* PChar, uint16 Title);                 // Set title if not, save and update player

	int32	hasPetAbility(CCharEntity* PChar, uint16 AbilityID);	    // Same as Ability but for pet commands (e.g. Healing Ruby)
	int32	addPetAbility(CCharEntity* PChar, uint16 AbilityID);
	int32	delPetAbility(CCharEntity* PChar, uint16 AbilityID);

	int32	hasTrait(CCharEntity* PChar, uint8 TraitID);	            // Check if pchar has trait by traitid and jobid
	int32	addTrait(CCharEntity* PChar, uint8 TraitID);	            // Add trait by traitid and jobid
	int32	delTrait(CCharEntity* PChar, uint8 TraitID);	            // Delete trait by traitid and jobid

	int32	addWeaponSkill(CCharEntity* PChar, uint16 WeaponSkillID);   // Declaration of function to add weapon skill
	int32	hasWeaponSkill(CCharEntity* PChar, uint16 WeaponSkillID);   // Declaration of function to check for weapon skill
	int32	delWeaponSkill(CCharEntity* PChar, uint16 WeaponSkillID);   // Declaration of function to delete weapon skill

	void	SaveCharJob(CCharEntity* PChar, JOBTYPE job);		        // Holds the level of the selected character's profession
	void	SaveCharExp(CCharEntity* PChar, JOBTYPE job);		        // Store experience for their chosen profession character
	void	SaveCharEquip(CCharEntity* PChar);					        // Store the equipment and the appearance of the character
	void	SaveCharPosition(CCharEntity* PChar);				        // Save the position of the character
	void	SaveMissionsList(CCharEntity* PChar);                       // Save the missions list
	void	SaveQuestsList(CCharEntity* PChar);					        // Save the quest list
    void    SaveFame(CCharEntity* PChar);                               // Save area fame / reputation
	void	SaveZonesVisited(CCharEntity* PChar);				        // Save the visited area
	void	SaveKeyItems(CCharEntity* PChar);					        // Save the key items
	void	SaveCharInventoryCapacity(CCharEntity* PChar);              // Save Character inventory capacity
	void	SaveSpells(CCharEntity* PChar);						        // Store memorized spells
	void	SaveLearnedAbilities(CCharEntity* PChar);					// Saved learned abilities (corsair rolls)
    void    SaveTitles(CCharEntity* PChar);						        // Save the honored title
	void	SaveCharStats(CCharEntity* PChar);					        // Store the flags, the current values ​​zhihney, mana and professions
    void    SaveCharGMLevel(CCharEntity* PChar);                        // Saves the char's GM level and nameflags
    void    mentorMode(CCharEntity* PChar);                             // Changes char's mentor status
    void    SaveLanFlag(CCharEntity* PChar);                            // Saves the char's LanFlag
	void	SaveCharNation(CCharEntity* PChar);							// Save the character's nation of allegiance.
	void	SaveCharSkills(CCharEntity* PChar, uint8 skillID);	        // Saves the character's skill
	void	SaveCharPoints(CCharEntity* PChar);							// Conquest point, Nation TP
	void	SaveDeathTime(CCharEntity* PChar);							// Saves when this character last died.
	void	SavePlayTime(CCharEntity* PChar);							// Saves this characters total play time.
	bool	hasMogLockerAccess(CCharEntity* PChar);						// True if have access, false otherwise.

    uint32  AddExpBonus(CCharEntity* PChar, uint32 exp);
    void    ResetAllTwoHours();

	uint32	GetClientIP(CCharEntity* PChar);

    void    RemoveAllEquipment(CCharEntity* PChar);

	uint16	AvatarPerpetuationReduction(CCharEntity* PChar);

	void	SaveCharUnlockedWeapons(CCharEntity* PChar);
	void	LoadCharUnlockedWeapons(CCharEntity* PChar);
	void	loadCharWsPoints(CCharEntity* PChar);
	void	saveCharWsPoints(CCharEntity* PChar, uint16 indexid, int32 points);

    void    OpenSendBox(CCharEntity* PChar);
    void    RecoverFailedSendBox(CCharEntity* PChar);

    bool    CheckAbilityAddtype(CCharEntity* PChar, CAbility* PAbility);

    void    RemoveStratagems(CCharEntity* PChar, CSpell* PSpell);

    void    RemoveAllEquipMods(CCharEntity* PChar);
    void    ApplyAllEquipMods(CCharEntity* PChar);

	void	ClearTempItems(CCharEntity* PChar);
};

#endif
